package com.jhws.business.device.api;

import java.text.SimpleDateFormat;
import java.util.ArrayList;

import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import com.jhws.business.card.bo.*;
import com.jhws.business.comm.bo.TblBuildingDimBo;
import com.jhws.business.comm.bo.TblCommDimBo;
import com.jhws.business.device.bo.*;
import com.jhws.business.device.service.DeviceService;
import com.jhws.common.base.bo.JsonRespData;
import com.jhws.core.exception.BizException;
import com.jhws.business.comm.service.ITblBuildingDimService;
import com.jhws.business.comm.service.ITblCommDimService;
import com.jhws.core.log.bo.LogConstants;
import com.jhws.util.*;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.jhws.business.card.service.ITblCardDimService;
import com.jhws.business.card.TblCardRecordServiceImpl;

@Controller
@RequestMapping("/v2/deviceInfo")
public class deviceApiV2 extends deviceCtrl {

    @Resource
    private RedisTemplate stringTemplate;
    @Resource
    private ITblCardDimService ICardService;
    @Resource
    private TblCardRecordServiceImpl cardRecordService;
    @Resource
    private ITblBuildingDimService IBuildingService;
    @Resource
    private ITblCommDimService ICommService;
    @Resource
    private ITblBuildingDimService IBuildingDimService;
    @Resource
    private DeviceService deviceService;

    @RequestMapping("anon/updateCardBlackList")
    @ResponseBody
    public JsonRespData updateCardBlackList(String devAccount, String timeStamp) {
        Long tStamp = (timeStamp == null) ? 0 : Long.valueOf(timeStamp);
        HashOperations<String, String, String> hashOperations = stringTemplate.opsForHash();
        String cachedTimeStamp = hashOperations.get(CardConstant.REDIS_CARD_TIMESTAMP, devAccount);
        Long cachedValue = cachedTimeStamp != null ? Long.valueOf(cachedTimeStamp) : 0;
        /* 假如本地同步时间已经是最新,不再查询 */
        if (tStamp >= cachedValue)
            return new JsonRespData("updateCardBlackList", -1, "没有可更新卡信息！");
        else {
            List<TblCardPerms> list = ICardService.findTblCardsWithTimestamp(devAccount, tStamp,false);
            List<String> blkList = new ArrayList<>();
            List<String> whiteList = new ArrayList<>();
            tStamp = (long) 0;
            for (TblCardPerms perm : list) {
                if (perm.getEnable().equals(CardConstant.CARD_PERM_BLACKLIST))
                    blkList.add(perm.getCardNo());
                else if (perm.getEnable().equals(CardConstant.CARD_PERM_WHITELIST))
                    whiteList.add(perm.getCardNo());
                tStamp = perm.getTimeStamp() > tStamp ? perm.getTimeStamp() : tStamp;
            }

            HashMap<String, Object> dataMap = new HashMap<>();
            dataMap.put("blackList", blkList);
            dataMap.put("whiteList", whiteList);
            dataMap.put("timeStamp", tStamp);

            return new JsonRespData("updateCardBlackList", 1, dataMap);
        }
    }

    @RequestMapping("anon/cardRecord")
    @ResponseBody
    public JsonRespData cardRecord(String cardRecordList, String deviceNum) throws Exception {
        List<CardRecord> cList = JSON.parseArray(cardRecordList, CardRecord.class);
        TblCardRecord cardRecord;
        String commName = null, deviceInfo = null;
        String commCode = AccountsUtils.getCommCode(deviceNum);
        if (AccountsUtils.devicesType(deviceNum) == DeviceConstant.OUTDOOR_TYPE) {
            TblCommDimBo commDimBo = ICommService.findTblCommDimByCommCode(commCode);
            commName = commDimBo.getCommName();
            String areaName = AccountsUtils.getBuilding(deviceNum);
            String buildingName = AccountsUtils.getUnit(deviceNum);
            String buildingAliasName = IBuildingDimService.getBuildingAliasName(commCode, areaName, buildingName);
            deviceInfo = "[" + commDimBo.getCommName() + "] " + buildingAliasName + " " + buildingName + "单元 门口机-" + deviceNum.substring(11, 12);
        } else if (AccountsUtils.devicesType(deviceNum) == DeviceConstant.VILLA_TYPE) {
            commName = "别墅";
            deviceInfo = "别墅机-" + deviceNum;
        } else if (AccountsUtils.devicesType(deviceNum) == DeviceConstant.WALL_TYPE) {
            TblCommDimBo commDimBo = ICommService.findTblCommDimByCommCode(commCode);
            commName = commDimBo.getCommName();
            deviceInfo = commUtil.getGateDevAliasName(deviceNum, commDimBo.getGateDevAliasName());
        }

        for (CardRecord cRecord : cList) {
            TblCardDimBo cardDimBo = ICardService.findCardInfo(cRecord.getCardNumber());
            if (cardDimBo == null) {
                continue;
            } else {
                cardRecord = new TblCardRecord();
                cardRecord.setCardNo(cardDimBo.getCardNo());
                cardRecord.setCardType(cardDimBo.getCardType());
                cardRecord.setCommCode(cardDimBo.getCommCode());
                cardRecord.setOwnerCode(cardDimBo.getOwnerCode());
                cardRecord.setOwnerName(cardDimBo.getOwnerName());
                cardRecord.setRoomName(cardDimBo.getRoomName());
                cardRecord.setCommName(commName);
                cardRecord.setDeviceInfo(deviceInfo);
                cardRecord.setMac(cRecord.getMac());

                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateString = formatter.format(cRecord.getCardTime());
                cardRecord.setSwipeCardTime(DateUtil.stringDate(dateString));
                cardRecord.setDirection(cRecord.getDirection());

                /* 开锁信息写入日志 */
                LogDevUnlock devUnlock = new LogDevUnlock();
                devUnlock.setCommCode(cardRecord.getCommCode());
                devUnlock.setDevNumber(deviceNum);
                devUnlock.setRoomInfoNum(cardRecord.getRoomName());
                devUnlock.setType(DeviceConstant.UNLOCK_TYPE_CARD);
                devUnlock.setTime(cardRecord.getSwipeCardTime());
                devUnlock.setOwnerName(cardRecord.getOwnerName());
                devUnlock.setOwnerCode(cardRecord.getOwnerCode());
                devUnlock.setMac(cardRecord.getMac());
                LogHelper.getLogger(LogConstants.loggerUnlock).debug(GsonUtil.toJson(devUnlock, true),true);
                cardRecordService.save(cardRecord);
            }
        }
        return new JsonRespData("cardRecord", 1, null);
    }

    @SuppressWarnings("unchecked")
    @RequestMapping("anon/getDevNumber")
    @ResponseBody
    @Override
    public JsonRespData getDevInfoForUser(String Room, String type) throws Exception {
        if (Room.length() != 12 && Room.length() != 4)
            throw new BizException("-1", "getDevNumber", "房号长度不对");

        String comm = Room.substring(0, 4);
        String where = "where 1=1 and comm_code = '" + comm + "'";
        List<TblCommDimBo> comms = ICommService.findTblCommDimByWhere(where);

        switch (type) {
            case "owner": {
                DevsNumber info = new DevsNumber();
                int deviceNumber = IBuildingService.getUnitDevNumber(Room);
                if (deviceNumber < 0)
                    throw new BizException("-1", "getUnitDevNumber", "未查找到数据");
                info.setDevNumerOfUnit(deviceNumber);
                info.setGateDevNumber(comms.get(0).getGateDevNum());
                info.setManageDevNumber(comms.get(0).getManageDevNum());
                return new JsonRespData("getDevNumberForOwner", 1, info);
            }
            case "manager":
                List<TblBuildingDimBo> bos = IBuildingService.findTblBuildingDimByWhere(where);
                if (bos.size() == 0)
                    throw new BizException("-1", "getDevNumberForManager", "未查找到单元数据");
                List<DevsNumberOfUnit> unitDevsList = new ArrayList<>();
                for (TblBuildingDimBo bo : bos) {
                    DevsNumberOfUnit item = new DevsNumberOfUnit();
                    item.setAreaName(bo.getAreaName());
                    item.setBuildingName(bo.getBuildingName());
                    item.setDevNumber(bo.getDevNumber());
                    unitDevsList.add(item);
                }
                AllDevs alldevs = new AllDevs();
                alldevs.setDevsList(unitDevsList);
                alldevs.setGateDevNumber(comms.get(0).getGateDevNum());
                return new JsonRespData("getDevNumberForManager", 1, alldevs);
            case "outdoor": {
                DevsNumber info = new DevsNumber();
                info.setGateDevNumber(comms.get(0).getGateDevNum());
                info.setManageDevNumber(comms.get(0).getManageDevNum());

                List<Object[]> list = IBuildingService.findTblBuildingDimBySelectWhere(
                        "select min(CAST(area_name as integer)), sectionName, max(CAST(area_name as integer))",
                        " where 1=1 and comm_code = '" + comm + "'" + " group by section_name order by cast(area_name as int) ASC");
                List<AreaInfo> areaInfos = new ArrayList<>();
                for (Object[] objects : list) {
                    AreaInfo areaInfo = new AreaInfo();
                    areaInfo.setBaseAddr(Integer.valueOf(objects[0].toString()) - 1);
                    areaInfo.setAreaName(objects[1].toString() + "-区");
                    areaInfo.setCount(Integer.valueOf(objects[2].toString()));
                    areaInfos.add(areaInfo);
                }
                info.setAreaInfos(areaInfos);
                return new JsonRespData("getDevNumberForOutdoor", 1, info);
            }
            default:
                throw new BizException("-1", "getDevNumber", "unKnown type");
        }
    }

    @RequestMapping("anon/getCardDoorDevice")
    @ResponseBody
    JsonRespData getCardDoorDevice(String devNumber){
        return new JsonRespData("",1,ICardService.findCardDoorDevsBindings(devNumber));
    }

    /**
     * 开锁日志实时上传接口
     * @param devUnlocks 开锁记录列表
     * @return
     */
    @RequestMapping("anon/unlockRecord")
    @ResponseBody
    public JsonRespData unlockRecord(@RequestBody LogDevUnlock [] devUnlocks){
        if(devUnlocks.length > 0) {
            for(LogDevUnlock devUnlock : devUnlocks) {
                LogHelper.d(devUnlock.toString());
                String json = GsonUtil.toJson(devUnlock, true);
                LogHelper.getLogger(LogConstants.loggerUnlock).debug(json);
            }
            return new JsonRespData("",1,"");
        }
        return new JsonRespData("",-1,"空数据");
    }

    /**
     * 梯口机开关人脸权限
     * @param state
     * @param devNumber
     * @return
     * @throws Exception
     */
    @RequestMapping({"switchFacePerm"})
    @ResponseBody
    JsonRespData switchFacePerm(Integer state,String devNumber) throws Exception{
        String ret = deviceService.updateFacePerms(state,devNumber,null);
        if(ret != null)
            return new JsonRespData("",-1,ret);
        return new JsonRespData("",1,"操作成功");
    }
}
